package com.zkjl.protect_business.service.impl;

import com.zkjl.protect_business.common.Consts;
import com.zkjl.protect_business.common.UserThreadLocal;
import com.zkjl.protect_business.entity.NoticeRecord;
import com.zkjl.protect_business.entity.User;
import com.zkjl.protect_business.repository.NoticeRecordRepository;
import com.zkjl.protect_business.repository.UserRepository;
import com.zkjl.protect_business.service.LogService;
import com.zkjl.protect_business.service.NoticeRecordService;
import com.zkjl.protect_business.service.UserService;
import com.zkjl.protect_business.utils.RedisUtil;
import com.zkjl.protect_business.vo.UserOnlineVO;
import com.zkjl.protect_business.vo.statistic.GroupVO;
import com.zkjl.protect_business.vo.NoticeRecordVO;
import io.lettuce.core.cluster.RedisClusterPubSubReactiveCommandsImpl;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import static com.zkjl.protect_business.common.Consts.*;

@Service
public class NoticeRecordServiceImpl implements NoticeRecordService {


    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    ModelMapper modelMapper;
    @Autowired
    UserRepository userRepository;
    @Autowired
    UserService userService;
    @Autowired
    NoticeRecordRepository noticeRecordRepository;

    @Autowired
    LogService logService;

    @Override
    public List<GroupVO> getGroup(String noticeId) {

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        BoolQueryBuilder qb = QueryBuilders.boolQuery();
        qb.filter(new QueryStringQueryBuilder(noticeId).field("notice_id"));

        TermsAggregationBuilder builder = AggregationBuilders.terms("isRead").field("is_read");

        queryBuilder.withQuery(qb);
        queryBuilder.addAggregation(builder);
        NativeSearchQuery build = queryBuilder.build();
        build.setMaxResults(0);

        SearchHits<NoticeRecord> search = elasticsearchRestTemplate.search(build, NoticeRecord.class);
        Aggregations aggregations = search.getAggregations();
        ParsedStringTerms businessTypeName = aggregations.get("isRead");

        List<ParsedStringTerms.ParsedBucket> buckets = (List<ParsedStringTerms.ParsedBucket>) businessTypeName.getBuckets();

        List<GroupVO> collect = buckets.stream().map(bucket -> {
            String keyAsString = bucket.getKeyAsString();

            long docCount = bucket.getDocCount();
            GroupVO groupVO = new GroupVO();
            groupVO.setNum(docCount);
            groupVO.setKey(keyAsString);
            return groupVO;
        }).collect(Collectors.toList());

        return collect;

    }

    @Override
    public Long getReadNum(String noticeId, String status) {


        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        BoolQueryBuilder qb = QueryBuilders.boolQuery();

        qb.filter(new TermQueryBuilder("notice_id", noticeId));
        qb.filter(new TermQueryBuilder("is_read", status));

        queryBuilder.withQuery(qb);

        long count = elasticsearchRestTemplate.count(queryBuilder.build(), NoticeRecord.class);

        return count;
    }

    @Override
    public List<NoticeRecordVO> list(String noticeId, String isRead) {

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        BoolQueryBuilder qb = QueryBuilders.boolQuery();

        qb.filter(new TermQueryBuilder("notice_id", noticeId));
        qb.filter(new TermQueryBuilder("is_read", isRead));

        queryBuilder.withQuery(qb);

        SearchHits<NoticeRecord> search1 = elasticsearchRestTemplate.search(queryBuilder.build(), NoticeRecord.class);


        List<NoticeRecordVO> collect = search1.stream().map(SearchHit ->{

            NoticeRecord content = SearchHit.getContent();
            NoticeRecordVO recordVO = modelMapper.map(content, NoticeRecordVO.class);
            if ("未读".equals(isRead)) {
                String orgId = recordVO.getOrgId();
                List<UserOnlineVO> userOnlines = userService.getUserOnlines(orgId);
                recordVO.setUsers(userOnlines);

            }
            return recordVO;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public NoticeRecord confirm(String noticeId) {
        User user = UserThreadLocal.get();
        String orgId = user.getOrgId();
        String realName = user.getRealName();
        String phone = user.getPhone();

        //管理员查看不需要记录
        String sysRoleName = user.getSysRoleName();
        if (ADMIN.equals(sysRoleName)) {
            return null;
        }

        NoticeRecord noticeRecord = noticeRecordRepository.findByOrgIdAndAndNoticeId(orgId, noticeId);
        noticeRecord.setReadPeople(realName);
        noticeRecord.setReadTime(System.currentTimeMillis());
        noticeRecord.setContact(phone);
        noticeRecord.setIsRead("已读");

        NoticeRecord save = noticeRecordRepository.save(noticeRecord);

        logService.save("文件通知", noticeRecord.getName(), OPERATION_RECEIVE);


        return save;
    }
}
